package com.itheima.a05;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.type.MethodMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;

import java.io.IOException;
import java.util.Set;

/**
 * @author: AirMan
 * @date: 2025/4/10 21:56
 * @description:
 */
public class MyBeanPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanfactory) throws BeansException {
        try {
            String path = "classpath*:" + "com/itheima/a05" + "/**/*class";
            Resource[] resources = new PathMatchingResourcePatternResolver().getResources(path);
            for (Resource resource : resources) {
                CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
                MetadataReader reader = factory.getMetadataReader(resource);
                Set<MethodMetadata> methods = reader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
                String classAllName = reader.getClassMetadata().getClassName();
                String className = classAllName.substring(classAllName.lastIndexOf(".") + 1).toLowerCase();
                for (MethodMetadata method : methods) {
                    // 配置类充当的是一个工厂的角色，被 @Bean 注解的方法就是工厂方法
                    // 这里就不采用类名设置，我们把方法当作工厂方法
                    BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
                    // 设置工厂方法, 工厂方法名，工厂bean就是当前的类（已经被 spring 进行管理了）
                    builder.setFactoryMethodOnBean(method.getMethodName(), className);
                    // 注解的属性解析
                    String initMethod = method.getAnnotationAttributes(Bean.class.getName()).get("initMethod").toString();
                    // 开启构造方法和工厂方法的自动装配
                    builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
                    if (!initMethod.isEmpty()) {
                        builder.setInitMethodName(initMethod);
                    }
                    // 获取 beanDefinition
                    AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
                    // 注册 bean
                    beanfactory.registerBeanDefinition(method.getMethodName(), beanDefinition);
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
    }
}
